﻿using System;
using System.Windows;
using System.Windows.Input;
using System.Windows.Threading;

namespace Silverlight.Controls.ToolTips.Demo
{
    public partial class Home
    {
        private readonly DispatcherTimer mouseEnterTimer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(100) };
        private readonly DispatcherTimer delayTimer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(100) };
        private readonly DispatcherTimer displayTimeTimer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(100) };
        private readonly DispatcherTimer openAnimationTimer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(100) };
        private readonly DispatcherTimer closeAnimationTimer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(100) };

        private TimeSpan mouseEnterTicks = TimeSpan.Zero;
        private TimeSpan delayTicks = TimeSpan.Zero;
        private TimeSpan displayTimeTicks = TimeSpan.Zero;
        private TimeSpan openAnimationTicks = TimeSpan.Zero;
        private TimeSpan closeAnimationTicks = TimeSpan.Zero;

        public Home()
        {
            InitializeComponent();

            imageButton.IsEnabledChanged += OnButtonIsEnabledChanged;
            tooltipControl.OpenAnimationStarted += OnToolTipOpenAnimationStarted;
            tooltipControl.CloseAnimationStarted += OnToolTipCloseAnimationStarted;
            tooltipControl.OpenAnimation.Completed += OnToolTipOpenAnimationCompleted;
            tooltipControl.CloseAnimation.Completed += OnToolTipCloseAnimationCompleted;

            mouseEnterTimer.Tick += OnMouseEnterTimerTick;
            delayTimer.Tick += OnDelayTimerTick;
            displayTimeTimer.Tick += OnDisplayTimerTick;
            openAnimationTimer.Tick += OnOpenAnimationTimerTick;
            closeAnimationTimer.Tick += OnCloseAnimationTimerTick;
        }

        private void OnButtonIsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            if (!(bool)e.NewValue)
            {
                StopTimers();
            }
        }

        private void StopTimers()
        {
            if (openAnimationTimer.IsEnabled)
                openAnimationTimer.Stop();

            if (closeAnimationTimer.IsEnabled)
                closeAnimationTimer.Stop();

            if (displayTimeTimer.IsEnabled)
                displayTimeTimer.Stop();

            if (delayTimer.IsEnabled)
                delayTimer.Stop();

            if (mouseEnterTimer.IsEnabled)
                mouseEnterTimer.Stop();
        }

        private void OnDelayTimerTick(object sender, EventArgs e)
        {
            delayTicks = delayTicks.Add(delayTimer.Interval);
            DelayDuration.Text = FormatTimeSpanString(delayTicks);

            if (delayTicks.TotalSeconds == tooltipControl.InitialDelay.TimeSpan.TotalSeconds)
            {
                delayTimer.Stop();
            }
        }

        private void OnCloseAnimationTimerTick(object sender, EventArgs e)
        {
            closeAnimationTicks = closeAnimationTicks.Add(closeAnimationTimer.Interval);
            CloseAnimationDuration.Text = FormatTimeSpanString(closeAnimationTicks);

            var totalToolTipDuration = closeAnimationTicks.Add(displayTimeTicks).Add(openAnimationTicks);
            TotalToolTipDuration.Text = FormatTimeSpanString(totalToolTipDuration);
        }

        private void OnOpenAnimationTimerTick(object sender, EventArgs e)
        {
            openAnimationTicks = openAnimationTicks.Add(openAnimationTimer.Interval);
            OpenAnimationDuration.Text = FormatTimeSpanString(openAnimationTicks);

            var totalToolTipDuration = closeAnimationTicks.Add(displayTimeTicks).Add(openAnimationTicks);
            TotalToolTipDuration.Text = FormatTimeSpanString(totalToolTipDuration);
        }

        private void OnDisplayTimerTick(object sender, EventArgs e)
        {
            displayTimeTicks = displayTimeTicks.Add(displayTimeTimer.Interval);
            DisplayTimeDuration.Text = FormatTimeSpanString(displayTimeTicks);

            var totalToolTipDuration = closeAnimationTicks.Add(displayTimeTicks).Add(openAnimationTicks);
            TotalToolTipDuration.Text = FormatTimeSpanString(totalToolTipDuration);
        }

        private void OnMouseEnterTimerTick(object sender, EventArgs e)
        {
            mouseEnterTicks = mouseEnterTicks.Add(mouseEnterTimer.Interval);
            MouseEnterDuration.Text = FormatTimeSpanString(mouseEnterTicks);
        }

        private void OnToolTipCloseAnimationCompleted(object sender, EventArgs e)
        {
            closeAnimationTimer.Stop();
        }

        private void OnToolTipOpenAnimationCompleted(object sender, EventArgs e)
        {
            openAnimationTimer.Stop();
        }

        private void OnToolTipCloseAnimationStarted(object sender, EventArgs e)
        {
            displayTimeTimer.Stop();
            if (tooltipControl.DisplayTime.TimeSpan >= tooltipControl.CloseAnimation.Duration.TimeSpan)
            {
                closeAnimationTicks = TimeSpan.FromMilliseconds(100);
                closeAnimationTimer.Start();
            }
        }

        private void OnToolTipOpenAnimationStarted(object sender, EventArgs e)
        {
            if (tooltipControl.DisplayTime >= tooltipControl.OpenAnimation.Duration.TimeSpan)
            {
                openAnimationTicks = TimeSpan.FromMilliseconds(100);
                openAnimationTimer.Start();
            }
        }

        private void OnButtonClicked(object sender, RoutedEventArgs e)
        {
            imageButton.IsEnabled = false;
            enableImageButton.Visibility = Visibility.Visible;
        }

        private void OnEnableImageButtonClicked(object sender, RoutedEventArgs e)
        {
            imageButton.IsEnabled = true;
            enableImageButton.Visibility = Visibility.Collapsed;
        }

        private void OnToolTipOpened(object sender, RoutedEventArgs e)
        {
            displayTimeTimer.Start();
        }

        private void OnToolTipClosed(object sender, RoutedEventArgs e)
        {
            if (displayTimeTimer.IsEnabled)
                displayTimeTimer.Stop();
        }

        private void OnButtonMouseEnter(object sender, MouseEventArgs e)
        {
            tooltipLifeTimeVisualizer.StartVisualization(tooltipControl);
            mouseEnterTicks = TimeSpan.Zero;
            delayTicks = TimeSpan.Zero;
            displayTimeTicks = TimeSpan.Zero;
            openAnimationTicks = TimeSpan.Zero;
            closeAnimationTicks = TimeSpan.Zero;

            MouseEnterDuration.Text = FormatTimeSpanString(mouseEnterTicks);
            DelayDuration.Text = FormatTimeSpanString(delayTicks);
            DisplayTimeDuration.Text = FormatTimeSpanString(displayTimeTicks);
            OpenAnimationDuration.Text = FormatTimeSpanString(openAnimationTicks);
            CloseAnimationDuration.Text = FormatTimeSpanString(closeAnimationTicks);
            TotalToolTipDuration.Text = string.Empty;

            mouseEnterTimer.Start();

            if (tooltipControl.InitialDelay.TimeSpan.TotalSeconds > 0)
                delayTimer.Start();
        }

        private void OnButtonMouseLeave(object sender, MouseEventArgs e)
        {
            StopTimers();
        }

        private void OnPersistentToolTipChecked(object sender, RoutedEventArgs e)
        {
            DisplayTime.IsEnabled = false;
            tooltipControl.DisplayTime = Duration.Forever;
        }

        private void OnPersistentToolTipUnchecked(object sender, RoutedEventArgs e)
        {
            DisplayTime.IsEnabled = true;
            tooltipControl.DisplayTime = new Duration(TimeSpan.FromSeconds(DisplayTime.Value));
        }

        private static string FormatTimeSpanString(TimeSpan timeSpan)
        {
            var hours = timeSpan.Hours.ToString("00");
            var minutes = timeSpan.Minutes.ToString("00");
            var seconds = timeSpan.Seconds.ToString("00");
            var milliseconds = timeSpan.Milliseconds.ToString("000");

            return string.Format("{0}:{1}:{2},{3}", hours, minutes, seconds, milliseconds);
        }

        private void OnButtonResetDefaultsClicked(object sender, RoutedEventArgs e)
        {
            PersistentToolTip.IsChecked = false;
            tooltipControl.DisplayTime = new Duration(TimeSpan.FromSeconds(5));
            tooltipControl.InitialDelay = new Duration(TimeSpan.FromSeconds(1));
        }
    }
}